import { HttpException, HttpStatus, Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { toEntity } from "src/utils/dto2Entity";
import { Repository } from "typeorm";
import { DictionaryTypeDto } from "./dto/dictionary-type.dto";
import { SearchDictionaryTypeDto } from "./dto/search-dictionary-type.dto";
import { DictionaryTypeEntity } from "./entities/dictionary-type.entity";
import { PageResponseResult } from "@/common/tools/page.response.result";
import { TenantService } from "@/modules/tenant/tenant.service";

@Injectable()
export class DictionaryTypeService {
  constructor(private readonly tenantService: TenantService) {}
  @InjectRepository(DictionaryTypeEntity)
  private readonly dictionaryTypeRepository: Repository<DictionaryTypeEntity>;

  /**
   * 获取字典分类分页列表
   * @param searchDictionaryTypeDto 搜索dto
   */
  async getDictionaryTypePageList(
    tenantId: number,
    searchDictionaryTypeDto: SearchDictionaryTypeDto
  ) {
    const { page, keyword } = searchDictionaryTypeDto;
    const { current, size } = page;
    const skip = (current - 1) * size;
    const tenantRepository = await this.getTenantRepository(tenantId);
    const queryBuilder = tenantRepository.createQueryBuilder();
    if (keyword) {
      queryBuilder.where(`dictionaryType_name=:dictionaryTypeName`, {
        dictionaryTypeName: keyword,
      });
      queryBuilder.orWhere(`phone=:phone`, { phone: keyword });
    }
    const entities = await queryBuilder
      .orderBy("create_time", "DESC")
      .offset(skip)
      .limit(size)
      .getMany();
    page.total = await queryBuilder.getCount();
    const result = new PageResponseResult<DictionaryTypeEntity[]>(
      page.total,
      entities
    );
    return result;
  }

  /**
   * 获取字典分类列表
   */
  async getDictionaryTypeList(tenantId: number) {
    const tenantRepository = await this.getTenantRepository(tenantId);
    const entities = await tenantRepository.find();
    return entities;
  }

  /**
   * 根据字典编码获取字典子分类列表
   */
  async getDictionaryTypeListByPId(tenantId: number, dicTypeCode: string) {
    const entity = await this.getDictionaryTypeByDictionaryTypeId(
      tenantId,
      dicTypeCode
    );
    const tenantRepository = await this.getTenantRepository(tenantId);
    const entities = await tenantRepository.find({
      where: {
        pId: entity.id.toString(),
      },
    });
    return entities;
  }

  /**
   * 根据字典分类id获取字典分类信息
   * @param id 编号
   */
  async getDictionaryTypeById(tenantId: number, id: number) {
    const tenantRepository = await this.getTenantRepository(tenantId);
    const entity = await tenantRepository.findOne({
      where: {
        id,
      },
    });
    return entity;
  }

  /**
   * 根据字典分类名称获取字典分类信息
   * @param dicTypeName 字典分类名称
   */
  async getDictionaryTypeByDictionaryTypeName(
    tenantId: number,
    dicTypeName: string
  ) {
    const tenantRepository = await this.getTenantRepository(tenantId);
    const entity = await tenantRepository.findOneBy({
      dicTypeName,
    });
    return entity;
  }

  /**
   * 根据字典分类名称获取字典分类信息
   * @param dicTypeName 字典分类名称
   */
  async getDictionaryTypeByDictionaryTypeId(
    tenantId: number,
    dicTypeCode: string
  ) {
    const tenantRepository = await this.getTenantRepository(tenantId);
    const entity = await tenantRepository.findOneBy({
      dicTypeCode,
    });
    return entity;
  }

  /**
   * 创建字典分类
   * @param dictionaryTypeDto 字典分类dto
   */
  async createDictionaryType(
    tenantId: number,
    dictionaryTypeDto: DictionaryTypeDto
  ) {
    const tenantRepository = await this.getTenantRepository(tenantId);
    const dictionaryType = await tenantRepository.findOneBy({
      dicTypeName: dictionaryTypeDto.dicTypeName,
    });
    if (dictionaryType) {
      throw new HttpException(
        "操作失败,字典分类名已使用.",
        HttpStatus.BAD_REQUEST
      );
    }
    const dictionaryTypeEntity = new DictionaryTypeEntity();
    toEntity(dictionaryTypeDto, dictionaryTypeEntity);
    dictionaryTypeEntity.pId = "0";
    dictionaryTypeEntity.createTime = new Date();
    await tenantRepository.insert(dictionaryTypeEntity);
  }

  /**
   * 修改字典分类
   * @param id 编号
   * @param dictionaryTypeDto 字典分类dto
   */
  async updateDictionaryTypeById(
    tenantId: number,
    id: number,
    dictionaryTypeDto: DictionaryTypeDto
  ) {
    const dictionaryType = await this.getDictionaryTypeById(tenantId, id);
    if (!dictionaryType) {
      throw new HttpException(
        "操作失败,未找到字典分类信息.",
        HttpStatus.BAD_REQUEST
      );
    }
    const dictionaryTypeEntity = new DictionaryTypeEntity();
    toEntity(dictionaryTypeDto, dictionaryTypeEntity);
    const tenantRepository = await this.getTenantRepository(tenantId);
    await tenantRepository.update(id, dictionaryTypeEntity);
  }

  /**
   * 删除字典分类
   * @param id 编号
   */
  async removeDictionaryTypeById(tenantId: number, id: number) {
    const tenantRepository = await this.getTenantRepository(tenantId);
    await tenantRepository.delete(id);
  }
  private async getTenantRepository(
    tenantId: number
  ): Promise<Repository<DictionaryTypeEntity>> {
    const tenantConnection = await this.tenantService.getTenantConnection(
      tenantId
    );
    return tenantConnection.getRepository(DictionaryTypeEntity);
  }
}
